「★★★(三つ星)オープンデータ」はオープンデータの評価指標「5 Star OPEN DATA」の3段階目にあたるオープンデータです.
1段階目の「オープンライセンス(Open License;OL)であること」, 2段階目の「読み込み可能(Readable)であること」に加え,3段階目では 「オープンフォーマット(Open Format)であること」が求められます.
5 Star OPEN DATA」
狭義の意味でのオープンフォーマット(Open Format)は, ファイルの仕様,規格,構造が公開されており,権利問題もオープンとなっているフォーマット(ファイル形式)です. そのため,だれもが自由に読み書きすることができますし,だれもがファイル構造を自由に拡張したり,仕様を変更したり,することができます. まさにオープンなフォーマットなのです.
一方,オープンフォーマットの対比としてプロプライエタリ・フォーマット(Proprietary Format)があります. プロプライエタリ・フォーマットは,ファイル仕様,規格,構造が公開されておらず, 権利問題が生じる可能性があるファイル形式です. そのため,だれもが自由に読み書き可能とは言い難いのです.
広義の意味でのオープンフォーマットは, ファイル形式がオープンであることに加え, そのファイル形式に対応したソフトウェア・オペレーティングシステム(Operating System; OS)もオープンな状態にあり, 事実上,だれもが自由に読み書き可能な状態にあるファイル形式を指します.
たとえば,Microsoft Excelの代表的なファイル形式に Microsoft Office バイナリ ファイル形式(.xls)と Office Open XML形式(.xlsx)があります. Microsoft Office バイナリ ファイル形式(.xls)は, ファイル仕様が非公開状態にあるプロプライエタリ・フォーマットです. 基本的には,Microsoft Excelでなければ読み書きできず, だれもが自由に利用できるとは言い難い状態にあります. 他方で,Office Open XML形式(.xlsx)は標準化されたファイル形式で, ファイル仕様は公開されています.しかしながら,その仕様はだれもが自由に閲覧できる状況にはありません(購入が必要). また,事実上,商用ソフトウェアMicrosoft Excelでの処理が前提であり,だれもが自由にとはいきません. そのため,Office Open XML形式は狭義の意味でのオープンフォーマットではあるのですが,広義の意味でのオープンフォーマットではありません.
「★★★(三つ星)オープンデータ」に求められているのは広義の意味でのオープンフォーマットであり, 真の意味で「だれもが自由に利用可能」であることが求められます.
オープンフォーマットの代表例としてCSV(Conmma-Separeted Values)形式が有名です. CSV形式はデータをカンマ(,)で区切ったテキストファイルです.とてもシンプルなファイル形式であるので, 様々なソフトウェアでの読み書きが可能となっており,OS依存もありません.まさに誰もが処理可能な状態にあるのです.
このように「★★★(三つ星)オープンデータ」は真の意味でのオープンデータといえます. オープンデータの思想は「★★★(三つ星)オープンデータ」を指しています. 「誰もが自由に使えて再利用でき、かつ再配布できる」という理想を達成するには, 「★★★(三つ星)オープンデータ」をを目指す必要があるのです.
東京電力のでんき予報http://www.tepco.co.jp/forecast/index-j.htmlにアクセスします.
データのダウンロードにある電力の使用状況データ>CSVデータダウンロードをクリックし,CSVデータをダウンロードします(ファイル名は「juyo-j.csv」).
※CSVデータは毎時更新なので注意しましょう.
また,過去の電力使用実績データのダウンロードから課題で利用する2016年の電気使用実績データをダウンロードします.
http://www.tepco.co.jp/forecast/html/images/juyo-2016.csv
あわせて2014年のデータもダウンロードします(HPにリンクが存在しないので以下URLから直接ダウンロードしてください).
http://www.tepco.co.jp/forecast/html/images/juyo-2014.csv
ダウンロードした3つのCSVファイルをRの作業ディレクトリに移動させます.
Rの作業ディレクトリがわからない場合はRコンソールで以下コマンドを実行します.
getwd()
実行結果として作業ディレクトリが表示されます.
電力の使用状況データ「juyo-j.csv」を可視化する前にデータの中身をみてみましょう.テキストエディタまたはExcelでデータを開いてください.全部で7つの表データから構成されているのがわかると思います.
本日はこのうち8行目から始まる時間毎の表データおよび43行目から始まる5分毎の表データを利用します.
まずは時間毎の使用状況データを可視化します.
スクリプトエディタを開き,以下コードを入力し,実行してください.
#ライブラリの読み込み.なければインストールする.
if(!require(ggplot2)){
install.packages("ggplot2")
library(ggplot2)
}
#游ゴシック体を使う
if(.Platform$OS.type=="windows")
windowsFonts(yugo=windowsFont("Yu Gothic"))
if(capabilities("aqua"))
quartzFonts(yugo=quartzFont(rep("YuGo-Medium",4)))
# CSVファイルを読み込む
# header = TRUE :1行目をヘッダーとして処理する
# skip = 7 :先頭行より7行スキップしてから読み込みを始める
# nrow = 24 :24行分のデータを読み込む
# fileEncoding="Shift_JIS" :ファイルの文字コードが「Shift_JIS」と想定して処理する
csv<-read.csv("juyo-j.csv",header=TRUE,skip=7,nrow=24,fileEncoding="Shift_JIS")
# 列名の設定
colnames(csv) <- c("date","time","pow","yosoku","usage")
g<-ggplot(data=csv,aes(x=time,y=pow,group=date))
g<-g+geom_line()
g<-g+theme_gray(base_family = "yugo")
g<-g+theme(axis.text.x = element_text(angle = 90, hjust = 1))
g<-g+ylab("当日実績(万kW)")+xlab("時間")+ggtitle("電力の使用状況")
g実行すると電力の使用状況グラフが表示されます(ダウンロードする日時により表示結果は異なります).
本日のキーポイントは read.csv 関数の使い方ですが,それ以外はこれまでと同じなので戸惑うことは無いと思います.
それでは,さっそく,本日のキーポイントである read.csv 関数の使い方をみてみましょう.
csv<-read.csv("juyo-j.csv",header=TRUE,skip=7,nrow=24,fileEncoding="Shift_JIS")
関数の引数にはファイル名「“juyo-j.csv”」の他に「header = TRUE」「skip=7」「nrow=24」「fileEndocing=“Shift_JIS”」が渡されています.
それぞれの引数の意味は次のようになります.
| 引数 | 意味 |
|---|---|
| header | 1行目のデータをヘッダーとする(TRUE)か否か(FALSE)を指定する.デフォルト値はTRUE |
| skip | 読み込みをスキップする行数を指定する.「skip=7」の場合は,7行スキップしてからデータの読み込みを開始する(8行目から読み込みを開始する). |
| nrow | 読み込む行数を指定する.ヘッダー行は含まない. |
| fileEncoding | 読み込みファイルの文字コードを指定する. |
今回のCSVファイルのように, 一つのファイルに複数の表データが含まれる場合は, skip と nrow の組合せで目的の表データを取り出す必要がでてきます(読み込み後削除するのでも構いません).
また,OSとファイルの文字コードが異なる場合は,fileEncoding の指定が必要になってきます.
例えば,MacOSの場合は fileEncoding 指定を省略すると以下のように読み込みエラーとなります.
csv<-read.csv("juyo-j.csv",header=TRUE,skip=7,nrow=24)## Error in make.names(col.names, unique = TRUE): '<93><96><93><fa><8e><c0><90><d1>(<96><9c>kW)' に不正なマルチバイト文字があります
ファイルの文字コードはテキストエディタや nkf (https://ja.osdn.net/projects/nkf/) といったコマンドで調べることができます.
nkfの実行例.
$ nkf --guess juyo-j.csv
Shift_JIS (CRLF)
さて,もう一度さきほどのグラフをみてみましょう.何かおかしな点はありませんか?
そうです.X軸ラベルがおかしなことになっています.
read.csv 実行時, 文字列から因子(Factor)への変換処理が動いているのですが, そこで単純な文字列順で順位付けを行うことに問題があります.
csv$time## [1] 0:00 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00 9:00 10:00
## [12] 11:00 12:00 13:00 14:00 15:00 16:00 17:00 18:00 19:00 20:00 21:00
## [23] 22:00 23:00
## 24 Levels: 0:00 1:00 10:00 11:00 12:00 13:00 14:00 15:00 16:00 ... 9:00
read.csv の引数に「stringsAsFactors = FALSE」と設定すると 因子への変換処理は省略されますが,描画時の並び替えが必要となります.
今回のケースでは,行番号順にデータが並んでいるので, 行番号順にX軸ラベルを並び替えればよいことになります.
それでは並び替えをしてみましょう.
#行番号を列idに追加する.
csv$id<-1:nrow(csv)
#timeをidで並び替え
csv$time<-reorder(csv$time,csv$id)
csv$time## [1] 0:00 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00 9:00 10:00
## [12] 11:00 12:00 13:00 14:00 15:00 16:00 17:00 18:00 19:00 20:00 21:00
## [23] 22:00 23:00
## attr(,"scores")
## 0:00 1:00 10:00 11:00 12:00 13:00 14:00 15:00 16:00 17:00 18:00 19:00
## 1 2 11 12 13 14 15 16 17 18 19 20
## 2:00 20:00 21:00 22:00 23:00 3:00 4:00 5:00 6:00 7:00 8:00 9:00
## 3 21 22 23 24 4 5 6 7 8 9 10
## 24 Levels: 0:00 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00 9:00 ... 23:00
並び替え後のデータでグラフを描画します.
#timeをidで並び替えしてグラフを描画
g<-ggplot(data=csv,aes(x=time,y=pow,group=date))
g<-g+geom_line()+theme_gray(base_family = "yugo")
g<-g+theme(axis.text.x = element_text(angle = 90, hjust = 1))
g<-g+xlab(label = "time")+ggtitle("電力の使用状況")
ggeom_bar で棒グラフにしてみます.
g<-ggplot(data=csv,aes(x=time,y=pow,group=date))
g<-g+geom_bar(stat="identity")+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("電力の使用状況")geom_area で面グラフにしてみます.
g<-ggplot(data=csv,aes(x=time,y=pow,group=date))
g<-g+geom_area(stat="identity")+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("電力の使用状況")
gx軸をidにして, scale_x_continuous でラベルを付け直すこともできます.
g<-ggplot(data=csv,aes(x=id,y=pow,group=date))+geom_area(stat="identity")+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("電力の使用状況")
gg+scale_x_continuous(breaks=seq(1,nrow(csv),1),labels=seq(0,23),expand = c(0,0))scale_x_continuous を使うと, 6時間毎にラベルを付けると行ったことも可能となります.
g+scale_x_continuous(breaks=seq(1,nrow(csv),6),labels=seq(0,23,6),expand = c(0,0))#ちょっと加工
g+scale_x_continuous(breaks=seq(1,nrow(csv),6),labels=paste(seq(0,23,6),"時"),expand = c(0,0))つぎは juyo-2014.csv を可視化します.
#ファイル読み込み
csv3<-read.csv("juyo-2014.csv",skip = 2,fileEncoding = "Shift_JIS",stringsAsFactors = FALSE)
colnames(csv3)<-c("date","time","pow")
csv3$id<-1:nrow(csv3)
# x軸をidとする
ggplot(data=csv3,aes(x=id,y=pow))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("2014年の電力使用状況")X軸がidだとやはり分かりにくいですね.
ここはx軸を日付として処理させてみましょう.
as.Date を使って date列をDate型に変換します.
ggplot(data=csv3,aes(x=as.Date(date),y=pow))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("2014年の電力使用状況")日付順にデータが並んでいますが,日付だけだと時間単位の情報が抜け落ちてしまっています.
そこで,日時順でデータを並び替えるようにします. date列とtime列を結合すれば日時データとなるはずです.
# 日付と時間とタイムゾーン「JST」を結合
csv3$datetime<-paste(csv3$date,csv3$time,"JST")
ggplot(data=csv3,aes(x=as.POSIXct(datetime),y=pow))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("2014年の電力使用状況")それっぽく表示されました.
ggplot(data=csv3,aes(x=as.POSIXct(datetime,tz="Asia/Tokyo"),y=pow))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("2014年の電力使用状況")+scale_x_datetime(date_labels='%Y-%m')電力使用がもっとも多かった日を調べてみましょう.
tmp<-csv3[csv3$pow==max(csv3$pow),]
tmp## date time pow id datetime
## 5199 2014/8/5 14:00 4980 5199 2014/8/5 14:00 JST
xlim 関数を使って特定の範囲だけを描画します.今回は電力使用がもっとも多かった日の0:00 - 23:00 までの範囲を指定します.
ggplot(data=csv3,aes(x=as.POSIXct(datetime,tz="Asia/Tokyo"),y=pow))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("2014年電力使用最高値を記録した日")+scale_x_datetime(date_breaks = "1 hour")+xlim(as.POSIXct(paste(tmp$date,"0:00")),as.POSIXct(paste(tmp$date,"23:00")))でも,やぱり xlim よりも subset で可視化した方がスマートですね.
tmp<-subset(csv3,csv3$date==csv3[csv3$pow==max(csv3$pow),]$date)
ggplot(data=tmp,aes(x=as.POSIXct(datetime,tz="Asia/Tokyo"),y=pow))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("2014年電力使用最高値を記録した日")+scale_x_datetime(date_breaks = "1 hour")気象庁のページから2014年の東京都の気温データをダウンロードします.
まず,以下アドレスにアクセスします.
http://www.data.jma.go.jp/gmd/risk/obsdl/index.php
「地点を選ぶ」>「東京」をクリックします.
もう一度「東京」をクリックします.
「項目を選ぶ」をクリックし,「データの種類」を「時別値」, 「項目」の「気温」にチェックをいれます.
「期間を選ぶ」をクリックし, 期間の範囲を「2014年1月1日」から「2014年12月31日」までとします.
「表示オプション」をクリックし, 内容を確認し,「CSVファイルをダウンロード」をクリックします.
「data.csv」がダウンロードされます.ファイル名を「jma.2014.kion.csv」に変更し,Rの作業ディレクトリに置いてください.
それではさっそくダウンロードしたファイルを可視化してみましょう.
csv4<-read.csv("jma.2014.kion.csv",skip = 4,fileEncoding = "Shift_JIS",stringsAsFactors = FALSE)
csv4<-csv4[,1:2]
colnames(csv4)<-c("datetime","temp")
csv4$id<-1:nrow(csv4)
csv4$datetime<-as.POSIXct(csv4$datetime,tz="Asia/Tokyo")
ggplot(data=csv4,aes(x=datetime,y=temp))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "日時")+ylab(label="気温")+ggtitle("東京の気温(2014年)")最高気温を記録した日時を調べてみましょう.
csv4[csv4$temp==max(csv4$temp),]## datetime temp id
## 5198 2014-08-05 14:00:00 35.5 5198
使用電力の最高値を記録した日と同じですね. 使用電力と気温には関係があるのかもしれません.
二種類のデータを結合して,散布図として可視化してみましょう.
csv3<-transform(csv3,temp=csv4$temp)
ggplot(data=csv3,aes(x=temp,y=pow))+geom_point()+theme_gray(base_family = "yugo")+xlab(label = "気温")+ylab(label="使用電力(万kW)")+ggtitle("東京電力の使用状況と東京都の気温(2014)")回帰曲線を追加してみましょう.
#回帰曲線を書いてみる
ggplot(data=csv3,aes(x=temp,y=pow))+geom_point()+theme_gray(base_family = "yugo")+xlab(label = "気温")+ylab(label="使用電力(万kW)")+ggtitle("東京電力の使用状況と東京都の気温(2014)")+stat_smooth(se=TRUE)なんとなく使用電力と気温の間には関係がありそうです.
ところで曜日別に見てみるとどうなるでしょうか.
weekdays 関数を用いると,日付から曜日を求めることができます.
#日付から曜日を求める
csv3$days<-weekdays(as.POSIXct(csv3$date,tz="Asia/Tokyo"))
#曜日毎に色分けしてみる
ggplot(csv3,aes(x=temp,y=pow,color=days))+geom_point()+theme_gray(base_family = "yugo")+xlab(label = "気温")+ylab(label="使用電力(万kW)")+ggtitle("東京電力の使用状況と東京都の気温(2014)")なんとなく土日の方が使用電力が低そうです.
さっそく確認してみましょう.
#一度すべてを平日にする
csv3$flag<-"平日"
#days列の値が土曜日または日曜日だったら土日とする
csv3[csv3$days %in% c("土曜日","日曜日"),]$flag<-"土日"
#色分けを平日と土日で行う
ggplot(csv3,aes(x=temp,y=pow,color=flag))+geom_point()+theme_gray(base_family = "yugo")+xlab(label = "気温")+ylab(label="使用電力(万kW)")+ggtitle("東京電力の使用状況と東京都の気温(2014)")これまたなんとなくですが平日の方が使用電力が多いようです.
ggplot(data=csv3,aes(x=as.POSIXct(datetime,tz="Asia/Tokyo"),y=pow,color=flag))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "time")+ggtitle("2014年の電力使用状況")+scale_x_datetime(date_labels='%Y-%m')csv4$flag<-"平日"
csv4$days<-weekdays(csv4$datetime)
csv4[csv4$days %in% c("土曜日","日曜日"),]$flag<-"土日"
ggplot(data=csv4,aes(x=datetime,y=temp,color=flag))+geom_line()+theme_gray(base_family = "yugo")+theme(axis.text.x = element_text(angle = 90, hjust = 1))+xlab(label = "日時")+ylab(label="気温")+ggtitle("東京の気温(2014年)")+scale_x_datetime(date_labels='%Y-%m')今回は三つ星オープンデータの可視化を取り上げました. 一つ星,二つ星オープンデータに比べると, 可視化に取り組むまでの手順が大部簡略化されていたと思います. Excelファイル(二つ星)の場合は専用の拡張モジュールが必要でしたが, CSVファイル(三つ星)の場合は,Rの標準機能で処理が可能でした. 「オープンデータ」を名乗るのであれば三つ星は達成して欲しいところです.もし,「オープンデータ」を公開する側になるのであれば,三つ星の基準を満たすようにするとよいと思います.
以下の問題を解いてください. その際に用いたRスクリプトファイル,結果として得られた画像ファイル, 可視化に用いたデータファイルをZIPでまとめて提出してください.
ヒント:
例:
ヒント:
例:
Masaharu Hayashi を著作者とするこの 作品 は クリエイティブ・コモンズの 表示 4.0 国際 ライセンスで提供されています。